home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
tex
/
dvi
/
dvipssrc.zoo
/
afm2tfm.c
next >
Wrap
C/C++ Source or Header
|
1991-01-13
|
35KB
|
1,290 lines
/*
* This program converts AFM files to TeX TFM files, and optionally
* to TeX VPL files that retain all kerning and ligature information.
* Both files make the characters not normally encoded by TeX available
* by character codes greater than 127.
*/
/* (Modified by Don Knuth from Tom Rokicki's pre-VPL version.) */
#include <stdio.h>
#ifdef SYSV
#include <string.h>
#else
#ifdef VMS
#include <string.h>
#else
#include <strings.h>
#endif
#endif
#include <math.h>
#ifdef MSDOS
#define WRITEBIN "wb"
#else
#define WRITEBIN "w"
#endif
char *texencoding[] = {
"Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma",
"Upsilon", "Phi", "Psi", "Omega", "arrowup", "arrowdown", "quotesingle",
"exclamdown", "questiondown", "dotlessi", "dotlessj", "grave", "acute",
"caron", "breve", "macron", "ring", "cedilla", "germandbls", "ae", "oe",
"oslash", "AE", "OE", "Oslash", "space", "exclam", "quotedbl", "numbersign",
"dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright",
"asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one",
"two", "three", "four", "five", "six", "seven", "eight", "nine", "colon",
"semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
"bracketright", "circumflex", "underscore", "quoteleft", "a", "b", "c", "d",
"e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
"t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright",
"tilde", "dieresis" } ;
/*
* The above layout corresponds to TeX Typewriter Type and is compatible
* with TeX Text because the position of ligatures is immaterial.
*/
/*
* This is what we store Adobe data in.
*/
struct adobeinfo {
struct adobeinfo *next ;
int adobenum, texnum, width ;
char *adobename ;
int llx, lly, urx, ury ;
struct lig *ligs ;
struct kern *kerns ;
struct pcc *pccs ;
int wptr, hptr, dptr, iptr ;
} *adobechars, *adobeptrs[256], *texptrs[256],
*uppercase[256], *lowercase[256] ;
struct lig {
struct lig *next ;
char *succ, *sub ;
} ;
struct kern {
struct kern *next ;
char *succ ;
int delta ;
} ;
struct pcc {
struct pcc *next ;
char * partname ;
int xoffset, yoffset ;
} ;
FILE *afmin, *vplout, *tfmout ;
char inname[200], outname[200] ; /* names of input and output files */
char buffer[255]; /* input buffer (modified while parsing) */
char obuffer[255] ; /* unmodified copy of input buffer */
char *param ; /* current position in input buffer */
char *fontname = "Unknown" ;
char *codingscheme = "Unspecified" ;
float italicangle = 0.0 ;
char fixedpitch ;
char makevpl ;
int xheight = 400 ;
int fontspace ;
int bc, ec ;
long cksum ;
float efactor = 1.0, slant = 0.0 ;
double newslant ;
char titlebuf[100] ;
void
error(s)
register char *s ;
{
extern void exit() ;
(void)fprintf(stderr, "%s\n", s) ;
if (obuffer[0]) {
(void)fprintf(stderr, "%s\n", obuffer) ;
while (param > buffer) {
(void)fprintf(stderr, " ") ;
param-- ;
}
(void)fprintf(stderr, "^\n") ;
}
if (*s == '!')
exit(1) ;
}
int
transform(x,y)
register int x,y ;
{
register double acc ;
acc = efactor * x + slant *y ;
return (int)(acc>=0? acc+0.5 : acc-0.5 ) ;
}
int
getline() {
register char *p ;
register int c ;
param = buffer ;
for (p=buffer; (c=getc(afmin)) != EOF && c != 10;)
*p++ = c ;
*p = 0 ;
(void)strcpy(obuffer, buffer) ;
if (p == buffer && c == EOF)
return(0) ;
else
return(1) ;
}
char *interesting[] = { "FontName", "ItalicAngle", "IsFixedPitch",
"XHeight", "C", "KPX", "CC", "EncodingScheme", NULL} ;
#define FontName (0)
#define ItalicAngle (1)
#define IsFixedPitch (2)
#define XHeight (3)
#define C (4)
#define KPX (5)
#define CC (6)
#define EncodingScheme (7)
#define NONE (-1)
int
interest(s)
char *s ;
{
register char **p ;
register int n ;
for (p=interesting, n=0; *p; p++, n++)
if (strcmp(s, *p)==0)
return(n) ;
return(NONE) ;
}
char *
mymalloc(len)
int len ;
{
register char *p ;
extern char *malloc() ;
p = malloc((unsigned)len) ;
if (p==NULL)
error("! out of memory") ;
return(p) ;
}
char *
paramnewstring() {
register char *p, *q ;
p = param ;
while (*p > ' ')
p++ ;
q = mymalloc((int)(p-param+1)) ;
if (*p != 0)
*p++ = 0 ;
(void)strcpy(q, param) ;
while (*p && *p <= ' ')
p++ ;
param = p ;
return(q) ;
}
char *
paramstring() {
register char *p, *q ;
p = param ;
while (*p > ' ')
p++ ;
q = param ;
if (*p != 0)
*p++ = 0 ;
while (*p && *p <= ' ')
p++ ;
param = p ;
return(q) ;
}
int
paramnum() {
register char *p ;
int i ;
p = paramstring() ;
if (sscanf(p, "%d", &i) != 1)
error("! integer expected") ;
return(i) ;
}
float
paramfloat() {
register char *p ;
float i ;
p = paramstring() ;
if (sscanf(p, "%f", &i) != 1)
error("! number expected") ;
return(i) ;
}
struct adobeinfo *
newchar() {
register struct adobeinfo *ai ;
ai = (struct adobeinfo *)mymalloc(sizeof(struct adobeinfo)) ;
ai->adobenum = -1 ;
ai->texnum = -1 ;
ai->width = -1 ;
ai->adobename = NULL ;
ai->llx = -1 ;
ai->lly = -1 ;
ai->urx = -1 ;
ai->ury = -1 ;
ai->ligs = NULL ;
ai->kerns = NULL ;
ai->pccs = NULL ;
ai->next = adobechars ;
adobechars = ai ;
return(ai) ;
}
struct kern *
newkern() {
register struct kern *nk ;
nk = (struct kern *)mymalloc(sizeof(struct kern)) ;
nk->next = NULL ;
nk->succ = NULL ;
nk->delta = 0 ;
return(nk) ;
}
struct pcc *
newpcc() {
register struct pcc *np ;
np = (struct pcc *)mymalloc(sizeof(struct pcc)) ;
np->next = NULL ;
np->partname = NULL ;
np->xoffset = 0 ;
np->yoffset = 0 ;
return(np) ;
}
struct lig *
newlig() {
register struct lig *nl ;
nl = (struct lig *)mymalloc(sizeof(struct lig)) ;
nl->next = NULL ;
nl->succ = NULL ;
nl->sub = NULL ;
return(nl) ;
}
void
expect(s)
char *s ;
{
if (strcmp(paramstring(), s) != 0) {
(void)fprintf(stderr, "%s expected: ", s) ;
error("! syntax error") ;
}
}
void
handlechar() { /* an input line beginning with C */
register struct adobeinfo *ai ;
register struct lig *nl ;
ai = newchar() ;
ai->adobenum = paramnum() ;
expect(";") ;
expect("WX") ;
ai->width = transform(paramnum(),0) ;
if (ai->adobenum >= 0 && ai->adobenum < 256) {
adobeptrs[ai->adobenum] = ai ;
cksum = (cksum<<1) ^ ai->width ;
}
expect(";") ;
expect("N") ;
ai->adobename = paramnewstring() ;
expect(";") ;
expect("B") ;
ai->llx = paramnum() ;
ai->lly = paramnum() ;
ai->llx = transform(ai->llx, ai->lly) ;
ai->urx = paramnum() ;
ai->ury = paramnum() ;
ai->urx = transform(ai->urx, ai->ury) ;
/* We need to avoid negative heights or depths. They break accents in
math mode, among other things. */
if (ai->lly > 0)
ai->lly = 0 ;
if (ai->ury < 0)
ai->ury = 0 ;
expect(";") ;
/* Now look for ligatures (which aren't present in fixedpitch fonts) */
while (*param == 'L') {
expect("L") ;
nl = newlig() ;
nl->succ = paramnewstring() ;
nl->sub = paramnewstring() ;
nl->next = ai->ligs ;
ai->ligs = nl ;
expect(";") ;
}
if (strcmp(ai->adobename, "space")==0) {
fontspace = ai->width ;
nl = newlig() ; /* space will act as zero-width Polish crossbar */
nl->succ = "l" ; /* when used by plain TeX's \l or \L macros */
nl->sub = "lslash" ;
nl->next = ai->ligs ;
ai->ligs = nl ;
nl = newlig() ;
nl->succ = "L" ;
nl->sub = "Lslash" ;
nl->next = ai->ligs ;
ai->ligs = nl ;
} else if (strcmp(ai->adobename, "question")==0) {
nl = newlig() ;
nl->succ = "quoteleft" ;
nl->sub = "questiondown" ;
nl->next = ai->ligs ;
ai->ligs = nl ;
} else if (strcmp(ai->adobename, "exclam")==